﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace Aludra.Core.Models
{
    public class MonsterZone : IField
    {
        private MonsterCard[] _monsterCards;

        private int _monsterCount;

        public int Count
        {
            get { return _monsterCount; }
        }

        public MonsterZone()
        {
            _monsterCards = new MonsterCard[5];
            _monsterCount = 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="size"></param>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public MonsterZone(int size)
        {
            if (size <= 0)
            {
                throw new ArgumentOutOfRangeException("size", "The size must be a positive number");
            }

            _monsterCards = new MonsterCard[size];
            _monsterCount = 0;
        }

        #region IField Members
        public FieldType FieldType
        {
            get { return FieldType.MonsterZone; }
        }

        public int Size
        {
            get { return _monsterCards.Length; }
        }

        public event EventHandler<CardsRemovedEventArgs> CardsRemoved;

        public event EventHandler<CardsAddedEventArgs> CardsAdded;

        #endregion

        public int IndexOf(MonsterCard item)
        {
            for (int i = this.Size - 1; i >= 0; i--)
            {
                if (_monsterCards[i].Equals(item))
                {
                    return i;
                }
            }
            return -1;
        }

        public void RemoveAt(int index)
        {
            if (index < this.Size && index >= 0)
            {
                throw new ArgumentOutOfRangeException("index", "The index must be a positive number and smaller than the size of monster zone");
            }

            // Copy to a temporary variable to be thread-safe.
            EventHandler<CardsRemovedEventArgs> temp = CardsRemoved;
            if (temp != null)
            {
                temp(this, new CardsRemovedEventArgs(this.FieldType, new[] { _monsterCards[index] }));
            }

            this[index] = null;
        }

        public void Remove(MonsterCard item)
        {
            int index = this.IndexOf(item);

            if (index >= 0)
            {
                // Copy to a temporary variable to be thread-safe.
                EventHandler<CardsRemovedEventArgs> temp = CardsRemoved;
                if (temp != null)
                {
                    temp(this, new CardsRemovedEventArgs(this.FieldType, new[] { _monsterCards[index] }));
                }

                this[index] = null;
            }
        }

        public MonsterCard this[int index]
        {
            get
            {
                return _monsterCards[index];
            }
            protected set
            {
                if (value == null && _monsterCards[index] != null)
                {
                    _monsterCount--;
                }
                else if (_monsterCards[index] == null && value != null)
                {
                    _monsterCount--;
                }
                _monsterCards[index] = value;
            }
        }

        public int Add(MonsterCard item)
        {
            int i = 0, size = this.Size;
            for (; i < size; i++)
            {
                if (_monsterCards[i] == null)
                {
                    this[i] = item;
                    EventHandler<CardsAddedEventArgs> tempAdded = this.CardsAdded;
                    if (tempAdded != null)
                    {
                        tempAdded(this, new CardsAddedEventArgs(this.FieldType, new[] { _monsterCards[i] }));
                    }
                    break;
                }
            }

            return i == size ? -1 : i;
        }

        public void Clear()
        {
            // Copy to a temporary variable to be thread-safe.
            EventHandler<CardsRemovedEventArgs> temp = CardsRemoved;
            if (temp != null)
            {
                temp(this, new CardsRemovedEventArgs(this.FieldType, _monsterCards));
            }

            for (int i = this.Size - 1; i >= 0; i--)
            {
                this[i] = null;
            }
        }

        public bool Contains(MonsterCard item)
        {
            return this.IndexOf(item) != -1;
        }
    }
}
